<!-- eslint-disable vue/multi-word-component-names -->
<script setup lang="ts">
import type { RouteRecordRaw } from 'vue-router'
import { isExternal } from '@/common/utils/validate'
// path-browserify 是一个用于浏览器环境的 Node.js path 模块的替代实现。
// 它提供了一组与 Node.js 的 path 库相似的功能，使得开发者可以在前端项目中方便地处理文件路径相关的操作，无需担心兼容性问题。
import path from 'path-browserify'
import Link from './Link.vue'
import type { SvgName } from '~virtual/svg-component'

interface Props {
  item: RouteRecordRaw // 路由项
  basePath?: string
}

const props = withDefaults(defineProps<Props>(), {
  basePath: '',
})

// 是否始终显示根菜单
const alwaysShowRootMenu = computed(() => props.item.meta?.alwaysShow)

// 显示的子菜单
// 使用 ?? 空值合并运算符，处理null或undefined的情况
const showingChildren = computed(
  () => props.item.children?.filter((child) => !child.meta?.hidden) ?? [],
)

// 显示的子菜单数量
const showingChildNumber = computed(() => showingChildren.value.length)

// 唯一的子菜单项
const theOnlyOneChild = computed(() => {
  const number = showingChildNumber.value
  switch (true) {
    case number > 1:
      return null
    case number === 1:
      return showingChildren.value[0]
    default:
      return { ...props.item, path: '' }
  }
})

// 解析路径
function resolvePath(routePath: string) {
  switch (true) {
    case isExternal(routePath):
      // 如果是外部链接（例如 https://example.com 或 mailto:user@example.com），直接返回 routePath
      return routePath
    case isExternal(props.basePath):
      // 如果父路径已经是外部链接，子路径不再有意义，直接使用父路径。
      return props.basePath
    default:
      // 将 props.basePath 和 routePath 组合成一个绝对路径。
      return path.resolve(props.basePath, routePath)
  }
}
</script>

<template>
  <template
    v-if="!alwaysShowRootMenu && theOnlyOneChild && !theOnlyOneChild.children"
  >
    <Link v-if="theOnlyOneChild.meta" :to="resolvePath(theOnlyOneChild.path)">
      <el-menu-item :index="resolvePath(theOnlyOneChild.path)">
        <SvgIcon
          v-if="theOnlyOneChild.meta.svgIcon"
          :name="theOnlyOneChild.meta.svgIcon as SvgName"
          class="svg-icon"
        />
        <component
          v-else-if="theOnlyOneChild.meta.elIcon"
          :is="theOnlyOneChild.meta.elIcon"
          class="el-icon"
        />
        <template v-if="theOnlyOneChild.meta.title" #title>
          <span class="title">{{ theOnlyOneChild.meta.title }}</span>
        </template>
      </el-menu-item>
    </Link>
  </template>
  <el-sub-menu v-else :index="resolvePath(props.item.path)" teleported>
    <template #title>
      <SvgIcon
        v-if="props.item.meta?.svgIcon"
        :name="props.item.meta.svgIcon as SvgName"
        class="svg-icon"
      />
      <component
        v-else-if="props.item.meta?.elIcon"
        :is="props.item.meta.elIcon"
        class="el-icon"
      />
      <span v-if="props.item.meta?.title" class="title">{{
        props.item.meta.title
      }}</span>
    </template>
    <template v-if="props.item.children">
      <Item
        v-for="child in showingChildren"
        :key="child.path"
        :item="child"
        :base-path="resolvePath(child.path)"
      />
    </template>
  </el-sub-menu>
</template>

<style lang="scss" scoped>
@use '@/common/assets/styles/mixins.scss';

.svg-icon {
  min-width: 1em;
  margin-right: 12px;
  font-size: 18px;
}

.el-icon {
  width: 1em !important;
  margin-right: 12px !important;
  font-size: 18px;
}

.title {
  @extend %ellipsis;
}
</style>
